package com.ynet.middleground.user.model;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ynet.middleground.user.bean.QuerySMSLogNoPageReq;
import com.ynet.middleground.user.dto.*;
import org.apache.commons.lang3.StringUtils;
import org.dozer.Mapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.base.Throwables;
import com.ifp.util.core.DateUtil;
import com.ynet.core.common.PagerInfo;
import com.ynet.core.exception.BusinessException;
import com.ynet.core.log.IfpLogger;
import com.ynet.host.HostConstants;
import com.ynet.middleground.user.bean.CheckSmsBalanceReq;
import com.ynet.middleground.user.bean.QuerySMSLogReq;
import com.ynet.middleground.user.bean.SendSmsReq;
import com.ynet.middleground.user.common.ErrorMessageConstant;
import com.ynet.middleground.user.dao.SmsLogMapper;
import com.ynet.middleground.user.entity.SmsLog;
import com.ynet.middleground.user.external.sms.SmsApiUri;
import com.ynet.middleground.user.external.sms.SmsConfig;
import com.ynet.middleground.user.utils.ApiUtil;

/**
 * SmsModel 短信发送相关服务
 *
 * @author suremotoo
 * @date 2022/12/20 21:38
 */
@Component
public class SmsModel {

    @Autowired
    private SmsConfig smsConfig;

    @Autowired
    private ApiUtil apiUtil;

    @Autowired
    private SmsLogModel smsLogModel;

    @Autowired
    private SmsLogMapper smsLogMapper;

    @Autowired
    private OrganizationManagementModel organizationManagementModel;

    @Autowired
    private Mapper dozerBeanMapper;

    /**
     * 发送短信接口服务
     *
     * @param req 发送短信请求信息
     * @return 发送短信结果信息
     */
    public SendSmsInfoDTO sendSms(SendSmsReq req) {
        if (req.getFormatId() != null) {
            if (!organizationManagementModel.checkFormatId(req.getFormatId(), req.getChannel())) {
                throw new BusinessException(ErrorMessageConstant.ECUC0067_MESSAGE, ErrorMessageConstant.ECUC0067_CODE);
            }
        }

        HashMap<String, Object> reqBody = new HashMap<>(16);
        reqBody.put("accesskey", req.getAppId());
        reqBody.put("secret", req.getAppSecret());
        reqBody.put("sign", req.getSign());
        reqBody.put("mobile", req.getMobile());
        reqBody.put("content", req.getContent());

        SmsLog smsLog = new SmsLog();
        smsLog.setRequestTime(LocalDateTime.now());
        smsLog.setIsSuccess(0);
        try {
            JSONObject resultObject = apiUtil.sendApiParam(null, reqBody, smsConfig.getApiHost() + SmsApiUri.SEND,
                HostConstants.HTTP_METHOD_POST, "发送短信");
            smsLog.setResponseTime(LocalDateTime.now());
            smsLog.setRequestMsg(JSON.toJSONString(req));
            if (resultObject != null) {
                smsLog.setResponseMsg(resultObject.toJSONString());
                if ("0".equals(resultObject.get("code"))) {
                    smsLog.setIsSuccess(1);
                    SendSmsInfoDTO dto = new SendSmsInfoDTO();
                    dto.setBatchId(resultObject.getString("batchId"));
                    smsLog.setBatchId(resultObject.getString("batchId"));
                    return dto;
                } else {
                    smsLog.setIsSuccess(0);
                    String errorMsg = String.valueOf(resultObject.getOrDefault("msg", "未获取到短信发送服务返回状态说明"));
                    smsLog.setErrMsg(errorMsg);
                    throw new BusinessException(errorMsg, String.valueOf(resultObject.get("code")));
                }
            }
        } catch (BusinessException be) {
            throw new BusinessException(be.getMessage(), be.getCode());
        } catch (Exception e) {
            IfpLogger.error(Thread.currentThread().getStackTrace()[1].getMethodName(), "发送短信服务异常，case: {}",
                Throwables.getStackTraceAsString(e));
            smsLog.setIsSuccess(0);
            smsLog.setErrMsg(e.getMessage());
        } finally {
            smsLogModel.recordDb(req, smsLog);
        }
        throw new BusinessException("发送短信服务异常", "ECUC0070");
    }

    /**
     * 查询短信账户余额
     *
     * @param req 查询短信余额请求信息
     * @return 短信账户余额信息
     */
    public SmsBalanceInfoDTO checkSmsBalance(CheckSmsBalanceReq req) {
        HashMap<String, Object> reqBody = new HashMap<>(16);
        reqBody.put("accesskey", req.getAppId());
        reqBody.put("secret", req.getAppSecret());
        JSONObject resultObject = apiUtil.sendApiParam(null, reqBody, smsConfig.getApiHost() + SmsApiUri.QUERY_ACCOUNT,
            HostConstants.HTTP_METHOD_POST, "查询短信账户余额");
        if (resultObject != null) {
            if ("0".equals(resultObject.get("code"))) {
                SmsBalanceInfoDTO dto = new SmsBalanceInfoDTO();
                dto.setData(resultObject.getString("data"));
                return dto;
            } else {
                String errorMsg = String.valueOf(resultObject.getOrDefault("msg", "未获取到查询短信余额服务返回状态说明"));
                throw new BusinessException(errorMsg, String.valueOf(resultObject.get("code")));
            }

        }
        throw new BusinessException("未获取到短信服务响应信息", "ECUC0070");
    }

    // 查询短信调用统计 2022-12-22 syf
    public SMSLogStatisticDto querySMSLogStatistic(QuerySMSLogReq req) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DateUtil.FORTER_DATE);

        if (StringUtils.isNotBlank(req.getRequestTimeStart())) {
            try {
                simpleDateFormat.parse(req.getRequestTimeStart());
                req.setRequestTimeStart(req.getRequestTimeStart() + " 00:00:00");
            } catch (ParseException e) {
                throw new BusinessException("调用时间起格式不正确", "ECRM0003");
            }
        }
        if (StringUtils.isNotBlank(req.getRequestTimeEnd())) {
            try {
                simpleDateFormat.parse(req.getRequestTimeEnd());
                req.setRequestTimeEnd(req.getRequestTimeEnd() + " 23:59:59");
            } catch (ParseException e) {
                throw new BusinessException("调用时间止格式不正确", "ECRM0003");
            }
        }
        // LambdaQueryWrapper<SmsLog> queryWrapperSMS = new LambdaQueryWrapper<>();
        // if(StringUtils.isNotBlank(req.getRequestTimeStart())){
        // queryWrapperSMS.ge(SmsLog::getRequestTime,req.getRequestTimeStart());
        // }
        // if(StringUtils.isNotBlank(req.getRequestTimeEnd())){
        // queryWrapperSMS.le(SmsLog::getRequestTime,req.getRequestTimeEnd());
        // }
        // if(req.getIsSuccess()!=null){
        // queryWrapperSMS.eq(SmsLog::getIsSuccess,req.getIsSuccess());
        // }
        // if(StringUtils.isNotBlank(req.getQueryChannel())){
        // queryWrapperSMS.eq(SmsLog::getChannel,req.getChannel());
        // }
        // if(req.getFormatId()!=null){
        // queryWrapperSMS.eq(SmsLog::getFormatId,req.getFormatId());
        // }
        // if(StringUtils.isNotBlank(req.getSignId())){
        // queryWrapperSMS.eq(SmsLog::getSignId,req.getSignId());
        // }
        // if(StringUtils.isNotBlank(req.getBatchId())){
        // queryWrapperSMS.eq(SmsLog::getBatchId,req.getBatchId());
        // }
        // if(StringUtils.isNotBlank(req.getAppKey())){
        // queryWrapperSMS.eq(SmsLog::getAppKey,req.getAppKey());
        // }
        PagerInfo pagerInfo = req.getPagerInfo();
        // Page<SmsLog> smsLogListPage = new Page<>(pagerInfo.getPageNum(), pagerInfo.getPageSize());
        // IPage<SmsLog> page = smsLogMapper.selectPage(smsLogListPage,queryWrapperSMS);
        // List<SmsLog> smsLogList = page.getRecords();
        // for(int i=0;i<smsLogList.size();i++){
        // smsLogList.get(i).setRequestTime(Date.from(smsLogList.get(i).getRequestTime().atZone(ZoneId.systemDefault()).toInstant()));
        // }
        // List<SmsLog> smsLogList = smsLogMapper.selectList(queryWrapperSMS);
        // List<QuerySMSLogDto> smsLogDtoList = BeanUtil.mapList(dozerBeanMapper, smsLogList, QuerySMSLogDto.class);
        Page<QuerySMSLogDto> querySMSLogDtoPage = new Page<>(pagerInfo.getPageNum(), pagerInfo.getPageSize());
        IPage<QuerySMSLogDto> smsLogDtoList = smsLogMapper.querySMSLogStatistic(querySMSLogDtoPage, req);
        pagerInfo.setTotal(smsLogDtoList.getTotal());
        req.setPagerInfo(pagerInfo);
        QuerySMSLogNoPageReq reqNoPage = dozerBeanMapper.map(req, QuerySMSLogNoPageReq.class);
        SMSLogStatisticDto smsLogStatisticDto = new SMSLogStatisticDto();
        smsLogStatisticDto.setAmountStatistics("0");
        smsLogStatisticDto.setQuantityStatistics("0");
        SMSLogStatisticDto temp = smsLogMapper.querySMSLogStatisticTotal(reqNoPage);
        if(temp!=null){
            smsLogStatisticDto = temp;
        }
        smsLogStatisticDto.setQuerySMSLogDtoList(smsLogDtoList.getRecords());
        return smsLogStatisticDto;
    }

    // 查询短信调用统计不分页 2023-1-6 syf
    public SMSLogStatisticDto querySMSLogStatisticNoPage(QuerySMSLogNoPageReq req) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DateUtil.FORTER_DATE);

        if (StringUtils.isNotBlank(req.getRequestTimeStart())) {
            try {
                simpleDateFormat.parse(req.getRequestTimeStart());
                req.setRequestTimeStart(req.getRequestTimeStart() + " 00:00:00");
            } catch (ParseException e) {
                throw new BusinessException("调用时间起格式不正确", "ECRM0003");
            }
        }
        if (StringUtils.isNotBlank(req.getRequestTimeEnd())) {
            try {
                simpleDateFormat.parse(req.getRequestTimeEnd());
                req.setRequestTimeEnd(req.getRequestTimeEnd() + " 23:59:59");
            } catch (ParseException e) {
                throw new BusinessException("调用时间止格式不正确", "ECRM0003");
            }
        }
//        List<QuerySMSLogDto> smsLogDtoList = smsLogMapper.querySMSLogStatisticNoPage(req);
        SMSLogStatisticDto smsLogStatisticDto = new SMSLogStatisticDto();
        smsLogStatisticDto.setAmountStatistics("0");
        smsLogStatisticDto.setQuantityStatistics("0");
        SMSLogStatisticDto temp = smsLogMapper.querySMSLogStatisticTotal(req);
        if(temp!=null){
            smsLogStatisticDto = temp;
        }
        smsLogStatisticDto.setQuerySMSLogDtoList(smsLogMapper.querySMSLogStatisticNoPage(req));
        return smsLogStatisticDto;
    }
}
